package com.example.tb_log.log;

import android.content.Context;
import android.os.Process;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * 崩溃处理器，用于捕获未处理的异常并记录日志
 */
public class TbCrashHandler implements Thread.UncaughtExceptionHandler {
    private static final String TAG = "TbCrashHandler";
    private static TbCrashHandler instance;
    private Thread.UncaughtExceptionHandler defaultHandler;
    private Context context;
    private String crashLogPath;
    private boolean isInitialized = false;

    private TbCrashHandler() {
        defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
    }

    public static TbCrashHandler getInstance() {
        if (instance == null) {
            synchronized (TbCrashHandler.class) {
                if (instance == null) {
                    instance = new TbCrashHandler();
                }
            }
        }
        return instance;
    }

    /**
     * 初始化崩溃处理器
     *
     * @param context      上下文
     * @param crashLogPath 崩溃日志保存路径
     */
    public void init(Context context, String crashLogPath) {
        if (isInitialized) {
            return;
        }
        this.context = context.getApplicationContext();
        this.crashLogPath = crashLogPath;
        Thread.setDefaultUncaughtExceptionHandler(this);
        isInitialized = true;
        Log.i(TAG, "崩溃处理器初始化完成");
    }

    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        try {
            String crashInfo = getCrashInfo(thread, ex);

            Log.e(TAG, "应用发生崩溃：\n" + crashInfo);


            saveCrashLogToFile(crashInfo);

            if (defaultHandler != null) {
                defaultHandler.uncaughtException(thread, ex);
            } else {
                Process.killProcess(Process.myPid());
                System.exit(1);
            }
        } catch (Exception e) {
            Log.e(TAG, "处理崩溃信息时发生错误", e);
        }
    }

    /**
     * 获取崩溃信息
     */
    private String getCrashInfo(Thread thread, Throwable ex) {
        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);

        // 打印时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
        String time = sdf.format(new Date());
        printWriter.println("崩溃时间: " + time);

        // 打印线程信息
        printWriter.println("\n线程信息:");
        printWriter.println("   线程名称: " + thread.getName());
        printWriter.println("   线程ID: " + thread.getId());
        printWriter.println("   线程优先级: " + thread.getPriority());
        printWriter.println("   线程状态: " + thread.getState());

        // 打印异常信息
        printWriter.println("\n异常信息:");
        printWriter.println("   异常类型: " + ex.getClass().getName());
        printWriter.println("   异常消息: " + ex.getMessage());
        printWriter.println("\n堆栈跟踪:");
        ex.printStackTrace(printWriter);

        // 打印设备信息
        printWriter.println("\n设备信息:");
        printWriter.println("   Android版本: " + android.os.Build.VERSION.RELEASE);
        printWriter.println("   SDK版本: " + android.os.Build.VERSION.SDK_INT);
        printWriter.println("   设备型号: " + android.os.Build.MODEL);
        printWriter.println("   设备品牌: " + android.os.Build.BRAND);
        printWriter.println("   设备制造商: " + android.os.Build.MANUFACTURER);
        printWriter.println("   设备产品名: " + android.os.Build.PRODUCT);
        printWriter.println("   设备硬件名: " + android.os.Build.HARDWARE);

        // 打印应用信息
        printWriter.println("\n应用信息:");
        try {
            printWriter.println("   应用版本名: " + context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName);
            printWriter.println("   应用版本号: " + context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode);
        } catch (Exception e) {
            printWriter.println("   获取应用信息失败: " + e.getMessage());
        }

        printWriter.close();
        return stringWriter.toString();
    }

    /**
     * 保存崩溃日志到文件
     */
    private void saveCrashLogToFile(String crashInfo) {
        if (crashLogPath == null || crashLogPath.isEmpty()) {
            Log.w(TAG, "崩溃日志保存路径未设置，无法保存崩溃日志");
            return;
        }

        try {
            File dir = new File(crashLogPath);
            if (!dir.exists()) {
                if (!dir.mkdirs()) {
                    Log.e(TAG, "创建崩溃日志目录失败: " + crashLogPath);
                    return;
                }
            }

            String fileName = "crash_" + System.currentTimeMillis() + ".txt";
            File file = new File(dir, fileName);

            FileOutputStream fos = new FileOutputStream(file);
            fos.write(crashInfo.getBytes());
            fos.close();

            Log.i(TAG, "崩溃日志已保存到: " + file.getAbsolutePath());
        } catch (IOException e) {
            Log.e(TAG, "保存崩溃日志失败", e);
        }
    }
} 